"""
配置同步管理器
确保Python和Java端配置格式一致性
"""

import json
from dataclasses import dataclass, asdict
from typing import Dict, Any, List, Optional, Union
from enum import Enum
import logging

class EngineType(Enum):
    """引擎类型枚举"""
    ASPOSE_JAVA = "ASPOSE_JAVA"
    APACHE_POI = "APACHE_POI"
    PYTHON_PPTX = "PYTHON_PPTX"

class QualityLevel(Enum):
    """质量级别枚举"""
    LOW = "LOW"
    NORMAL = "NORMAL"
    HIGH = "HIGH"

@dataclass
class SyncedPresentationSettings:
    """同步的演示文稿设置"""
    theme: str = "default"
    quality: QualityLevel = QualityLevel.NORMAL
    timeout_seconds: int = 300
    animation_engine: EngineType = EngineType.ASPOSE_JAVA
    fallback_engine: EngineType = EngineType.PYTHON_PPTX
    
    def to_python_dict(self) -> Dict[str, Any]:
        """转换为Python格式"""
        return {
            "theme": self.theme,
            "quality": self.quality.value.lower(),  # Python端使用小写
            "timeout_seconds": self.timeout_seconds,
            "animation_engine": self.animation_engine.value.lower(),
            "fallback_engine": self.fallback_engine.value.lower()
        }
    
    def to_java_dict(self) -> Dict[str, Any]:
        """转换为Java格式"""
        return {
            "theme": self.theme,
            "quality": self.quality.value,  # Java端使用大写
            "timeout_seconds": self.timeout_seconds,
            "animation_engine": self.animation_engine.value,
            "fallback_engine": self.fallback_engine.value
        }

@dataclass
class SyncedAnimationTiming:
    """同步的动画时序配置"""
    start_delay: float = 0.0
    duration: float = 1.0
    repeat_count: int = 1
    auto_reverse: bool = False

@dataclass
class SyncedAnimationConfig:
    """同步的动画配置"""
    target_element: str
    effect_type: str
    timing: SyncedAnimationTiming
    properties: Dict[str, Any] = None
    
    def __post_init__(self):
        if self.properties is None:
            self.properties = {}

class ConfigSyncManager:
    """配置同步管理器"""
    
    # 支持的动画效果类型映射
    ANIMATION_EFFECTS = {
        # 入场动画
        "fade_in": {"java": "Fade", "python": "fade_in"},
        "fly_in": {"java": "Fly", "python": "fly_in"},
        "wipe": {"java": "Wipe", "python": "wipe"},
        "split": {"java": "Split", "python": "split"},
        "wheel": {"java": "Wheel", "python": "wheel"},
        "zoom": {"java": "Zoom", "python": "zoom"},
        "bounce": {"java": "Bounce", "python": "bounce"},
        
        # 强调动画
        "pulse": {"java": "Pulse", "python": "pulse"},
        "spin": {"java": "Spin", "python": "spin"},
        "grow_shrink": {"java": "GrowShrink", "python": "grow_shrink"},
        
        # 退场动画
        "fade_out": {"java": "Fade", "python": "fade_out"},
        "fly_out": {"java": "Fly", "python": "fly_out"},
        "disappear": {"java": "Disappear", "python": "disappear"}
    }
    
    # 主题映射
    THEME_MAPPING = {
        "default": {"java": "default", "python": "default"},
        "blue": {"java": "blue", "python": "blue"},
        "dark": {"java": "dark", "python": "dark"},
        "minimal": {"java": "minimal", "python": "minimal"}
    }
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
    
    def normalize_settings(self, settings: Dict[str, Any], target_format: str = "java") -> Dict[str, Any]:
        """
        标准化设置格式
        
        Args:
            settings: 原始设置字典
            target_format: 目标格式 ("java" 或 "python")
        """
        try:
            # 创建同步设置对象
            synced_settings = SyncedPresentationSettings(
                theme=self._normalize_theme(settings.get("theme", "default")),
                quality=self._normalize_quality(settings.get("quality", "NORMAL")),
                timeout_seconds=int(settings.get("timeout_seconds", 300)),
                animation_engine=self._normalize_engine(settings.get("animation_engine", "ASPOSE_JAVA")),
                fallback_engine=self._normalize_engine(settings.get("fallback_engine", "PYTHON_PPTX"))
            )
            
            # 转换为目标格式
            if target_format.lower() == "java":
                return synced_settings.to_java_dict()
            else:
                return synced_settings.to_python_dict()
                
        except Exception as e:
            self.logger.error(f"设置标准化失败: {e}")
            return self._get_default_settings(target_format)
    
    def normalize_animation_effect(self, effect_type: str, target_format: str = "java") -> str:
        """
        标准化动画效果类型
        
        Args:
            effect_type: 原始效果类型
            target_format: 目标格式 ("java" 或 "python")
        """
        effect_lower = effect_type.lower()
        
        if effect_lower in self.ANIMATION_EFFECTS:
            return self.ANIMATION_EFFECTS[effect_lower][target_format.lower()]
        
        # 如果找不到映射，记录警告并返回原值
        self.logger.warning(f"未知的动画效果类型: {effect_type}")
        return effect_type
    
    def convert_animation_config(self, animation: Dict[str, Any], target_format: str = "java") -> Dict[str, Any]:
        """
        转换动画配置格式
        
        Args:
            animation: 原始动画配置
            target_format: 目标格式 ("java" 或 "python")
        """
        try:
            # 标准化时序配置
            timing_data = animation.get("timing", {})
            timing = SyncedAnimationTiming(
                start_delay=float(timing_data.get("start_delay", 0.0)),
                duration=float(timing_data.get("duration", 1.0)),
                repeat_count=int(timing_data.get("repeat_count", 1)),
                auto_reverse=bool(timing_data.get("auto_reverse", False))
            )
            
            # 标准化动画配置
            synced_animation = SyncedAnimationConfig(
                target_element=animation["target_element"],
                effect_type=self.normalize_animation_effect(animation["effect_type"], target_format),
                timing=timing,
                properties=animation.get("properties", {})
            )
            
            return asdict(synced_animation)
            
        except Exception as e:
            self.logger.error(f"动画配置转换失败: {e}")
            return animation  # 转换失败时返回原配置
    
    def validate_config_compatibility(self, config: Dict[str, Any]) -> List[str]:
        """
        验证配置兼容性
        
        Returns:
            List[str]: 兼容性问题列表
        """
        issues = []
        
        # 验证引擎兼容性
        settings = config.get("settings", {})
        engine = settings.get("animation_engine", "").upper()
        
        if engine not in [e.value for e in EngineType]:
            issues.append(f"不支持的动画引擎: {engine}")
        
        # 验证动画效果兼容性
        slides = config.get("slides", [])
        for i, slide in enumerate(slides):
            animations = slide.get("animations", [])
            for j, animation in enumerate(animations):
                effect_type = animation.get("effect_type", "").lower()
                if effect_type and effect_type not in self.ANIMATION_EFFECTS:
                    issues.append(f"幻灯片 {i+1} 动画 {j+1}: 不支持的效果类型 '{effect_type}'")
        
        return issues
    
    def _normalize_theme(self, theme: str) -> str:
        """标准化主题名称"""
        theme_lower = theme.lower()
        if theme_lower in self.THEME_MAPPING:
            return theme_lower
        self.logger.warning(f"未知主题: {theme}, 使用默认主题")
        return "default"
    
    def _normalize_quality(self, quality: Union[str, QualityLevel]) -> QualityLevel:
        """标准化质量级别"""
        if isinstance(quality, QualityLevel):
            return quality
        
        quality_upper = str(quality).upper()
        try:
            return QualityLevel(quality_upper)
        except ValueError:
            self.logger.warning(f"无效的质量级别: {quality}, 使用NORMAL")
            return QualityLevel.NORMAL
    
    def _normalize_engine(self, engine: Union[str, EngineType]) -> EngineType:
        """标准化引擎类型"""
        if isinstance(engine, EngineType):
            return engine
        
        engine_upper = str(engine).upper()
        
        # 处理常见的引擎名称变体
        engine_mapping = {
            "ASPOSE": EngineType.ASPOSE_JAVA,
            "ASPOSE_JAVA": EngineType.ASPOSE_JAVA,
            "POI": EngineType.APACHE_POI,
            "APACHE_POI": EngineType.APACHE_POI,
            "PYTHON": EngineType.PYTHON_PPTX,
            "PYTHON_PPTX": EngineType.PYTHON_PPTX
        }
        
        if engine_upper in engine_mapping:
            return engine_mapping[engine_upper]
        
        self.logger.warning(f"未知的引擎类型: {engine}, 使用ASPOSE_JAVA")
        return EngineType.ASPOSE_JAVA
    
    def _get_default_settings(self, target_format: str) -> Dict[str, Any]:
        """获取默认设置"""
        default_settings = SyncedPresentationSettings()
        
        if target_format.lower() == "java":
            return default_settings.to_java_dict()
        else:
            return default_settings.to_python_dict()
    
    def create_compatible_config(self, 
                               python_config: Dict[str, Any], 
                               target_engine: str = "ASPOSE_JAVA") -> Dict[str, Any]:
        """
        创建兼容的配置文件
        
        Args:
            python_config: Python端的配置
            target_engine: 目标引擎类型
        
        Returns:
            Dict[str, Any]: Java兼容的配置
        """
        try:
            # 标准化设置
            settings = self.normalize_settings(python_config.get("settings", {}), "java")
            settings["animation_engine"] = target_engine
            
            # 转换幻灯片配置
            java_slides = []
            for slide in python_config.get("slides", []):
                java_slide = {
                    "index": slide.get("index", 1),
                    "title": slide.get("title", ""),
                    "content": slide.get("content", []),
                    "layout": slide.get("layout", {})
                }
                
                # 转换动画配置
                if "animations" in slide:
                    java_animations = []
                    for animation in slide["animations"]:
                        java_animation = self.convert_animation_config(animation, "java")
                        java_animations.append(java_animation)
                    java_slide["animations"] = java_animations
                
                java_slides.append(java_slide)
            
            # 构建完整的Java配置
            java_config = {
                "metadata": python_config.get("metadata", {}),
                "settings": settings,
                "slides": java_slides
            }
            
            return java_config
            
        except Exception as e:
            self.logger.error(f"配置转换失败: {e}")
            raise ValueError(f"无法创建兼容配置: {e}")

# 全局配置同步管理器实例
_config_sync_manager = None

def get_config_sync_manager() -> ConfigSyncManager:
    """获取全局配置同步管理器实例"""
    global _config_sync_manager
    if _config_sync_manager is None:
        _config_sync_manager = ConfigSyncManager()
    return _config_sync_manager